package com.kingdee.eas.custom.gz.utils;

import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class DateTimeUtils extends com.kingdee.util.DateTimeUtils
{

	public static Date nDaysLater(Date date, int n)
	{
		if (date == null) throw new IllegalArgumentException("date can't be null!");
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DAY_OF_MONTH, n);

		return cal.getTime();
	}

	public static Date fiveYearsLater(Date date)
	{
		if (date == null) date = new Date();
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.YEAR, 5);

		return cal.getTime();
	}

	public static Date getDateOfNextMonth(Date date)
	{
		if (date == null)
		{
			throw new IllegalArgumentException();
		}
		else
		{
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.add(2, 1);
			return cal.getTime();
		}
	}

	public static Date getYearStart(Date date)
	{
		if (date == null)
		{
			throw new IllegalArgumentException();
		}
		else
		{
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.set(2, 0);
			cal.set(5, 1);
			cal.set(11, 0);
			cal.set(12, 0);
			cal.set(13, 0);
			cal.set(14, 0);
			return cal.getTime();
		}
	}

	public static Date getNextYearStart(Date date)
	{
		if (date == null)
		{
			throw new IllegalArgumentException();
		}
		else
		{
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.add(1, 1);
			cal.set(2, 0);
			cal.set(5, 1);
			cal.set(11, 0);
			cal.set(12, 0);
			cal.set(13, 0);
			cal.set(14, 0);
			return cal.getTime();
		}
	}

	public static Date getCustomMaximumDate()
	{
		Calendar cal = Calendar.getInstance();
		cal.set(2200, 0, 1, 0, 0, 0);
		cal.add(13, -1);
		return cal.getTime();
	}

	public static Date getCustomMinimumDate()
	{
		Calendar cal = Calendar.getInstance();
		cal.set(1900, 0, 1, 0, 0, 0);
		cal.add(13, -1);
		return cal.getTime();
	}

	public static Date getDateWithDefaultJavaDateStr(String toStringDate)
	{
		String defaultJavaStrFormat = "EEE MMM dd HH:mm:ss z yyyy";
		SimpleDateFormat formatter = new SimpleDateFormat(defaultJavaStrFormat, Locale.ENGLISH);
		Date date = null;
		try
		{
			date = formatter.parse(toStringDate);
		}
		catch (ParseException e)
		{
			e.printStackTrace();
		}
		return date;
	}

	public static Date getYesterdayDate(Date date)
	{
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(5, -1);
		Date yesterday = calendar.getTime();
		return yesterday;
	}

	public static Date getYesterdayDateWithZeroTime(Date date)
	{
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(5, -1);
		calendar.set(11, 0);
		calendar.set(12, 0);
		calendar.set(13, 0);
		calendar.set(14, 0);
		Date yesterday = calendar.getTime();
		return yesterday;
	}

	public static Date getPreDayStart(Date date)
	{
		if (date == null)
		{
			return null;
		}
		else
		{
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			calendar.add(5, -1);
			calendar.set(11, 0);
			calendar.set(12, 0);
			calendar.set(13, 0);
			calendar.set(14, 0);
			Date preDay = calendar.getTime();
			return preDay;
		}
	}

	public static Date getPreDayEnd(Date date)
	{
		if (date == null)
		{
			return null;
		}
		else
		{
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			calendar.add(5, -1);
			calendar.set(11, 23);
			calendar.set(12, 59);
			calendar.set(13, 59);
			calendar.set(14, 0);
			Date preDay = calendar.getTime();
			return preDay;
		}
	}

	public static Date getNextDateWithZeroTime(Date date)
	{
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(5, 1);
		calendar.set(11, 0);
		calendar.set(12, 0);
		calendar.set(13, 0);
		calendar.set(14, 0);
		Date newDate = calendar.getTime();
		return newDate;
	}

	/**
	 * @deprecated Method getDateWithZeroTime is deprecated
	 */

	public static Date getDateWithZeroTime(Date date)
	{
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(11, 0);
		calendar.set(12, 0);
		calendar.set(13, 0);
		calendar.set(14, 0);
		Date newDate = calendar.getTime();
		return newDate;
	}

	public static Date getDayStart(Date date)
	{
		if (date == null)
		{
			return null;
		}
		else
		{
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			calendar.set(11, 0);
			calendar.set(12, 0);
			calendar.set(13, 0);
			calendar.set(14, 0);
			Date newDate = calendar.getTime();
			return newDate;
		}
	}

	public static Date getNextDayStart(Date date)
	{
		if (date == null)
		{
			return null;
		}
		else
		{
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			calendar.add(5, 1);
			calendar.set(11, 0);
			calendar.set(12, 0);
			calendar.set(13, 0);
			calendar.set(14, 0);
			Date newDate = calendar.getTime();
			return newDate;
		}
	}

	public static Date getDayEnd(Date date)
	{
		if (date == null)
		{
			return null;
		}
		else
		{
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			calendar.set(11, 23);
			calendar.set(12, 59);
			calendar.set(13, 59);
			calendar.set(14, 0);
			Date newDate = calendar.getTime();
			return newDate;
		}
	}

	public static String getDateStrWithTime(Date date)
	{
		return getDateString(date, "yyyy-MM-dd HH:mm:ss");
	}

	public static String getDateStrWithZeroTime(Date date)
	{
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(11, 0);
		calendar.set(12, 0);
		calendar.set(13, 0);
		calendar.set(14, 0);
		Date newDate = calendar.getTime();
		SimpleDateFormat format = new SimpleDateFormat();
		format.applyPattern("yyyy-MM-dd HH:mm:ss");
		String dateStr = format.format(newDate);
		return dateStr;
	}

	public static Date getDateOfLastMonth(Date date)
	{
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(2, calendar.get(2) - 1);
		Date dateOfLastMonth = calendar.getTime();
		return dateOfLastMonth;
	}

	public static Date get1stDayOfTheMonth(Date date)
	{
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(5, 1);
		calendar.set(11, 0);
		calendar.set(12, 0);
		calendar.set(13, 0);
		calendar.set(14, 0);
		Date firstDateOfLastMonth = calendar.getTime();
		return firstDateOfLastMonth;
	}

	public static Date getLastDayOfMonth(Date date)
	{
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(5, 1);
		calendar.set(11, 0);
		calendar.set(12, 0);
		calendar.set(13, 0);
		calendar.set(14, 0);
		calendar.add(2, 1);
		calendar.add(5, -1);
		Date lastDayOfMonth = calendar.getTime();
		return lastDayOfMonth;
	}

	public static String getDateStrWithZeroTime(Date date, String pattern)
	{
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(11, 0);
		calendar.set(12, 0);
		calendar.set(13, 0);
		calendar.set(14, 0);
		Date newDate = calendar.getTime();
		SimpleDateFormat format = new SimpleDateFormat();
		format.applyPattern(pattern);
		String dateStr = format.format(newDate);
		return dateStr;
	}

	public static int dateDiffInDays(Date endDay, Date startingDay)
	{
		long intervalInMillis = getDayStart(endDay).getTime() - getDayStart(startingDay).getTime();
		long intervalInDays = intervalInMillis / getIntervalForOneDayInMillis();
		return (new Long(intervalInDays)).intValue();
	}

	public static int dateDiffInDay(Date startDate, Date endDate)
	{
		long intervalInMillis = getDayStart(endDate).getTime() - getDayStart(startDate).getTime();
		long intervalInDays = intervalInMillis / getIntervalForOneDayInMillis();
		int intervalInDay = (new Long(intervalInDays)).intValue();
		return intervalInDay;
	}

	public static int dateDiffInMonths(Date fromDate, Date toDate)
	{
		int mons = (toDate.getYear() - fromDate.getYear()) * 12 + (toDate.getMonth() - fromDate.getMonth());
		return mons;
	}

	public static int dateDiffInWeeks(Date fromDate, Date toDate)
	{
		int weeks = weekNumber(getTimestamp(toDate.getTime())) - weekNumber(getTimestamp(fromDate.getTime()));
		return weeks;
	}

	public static int dateDiffInQuarters(Date fromDate, Date toDate)
	{
		int Quarters = quarterNumber(getTimestamp(toDate.getTime())) - quarterNumber(getTimestamp(fromDate.getTime()));
		return Quarters;
	}

	public static int dateDiffInYears(Date fromDate, Date toDate)
	{
		return getYear(toDate) - getYear(fromDate);
	}

	public static Timestamp getTimestamp(long time)
	{
		return new Timestamp(time);
	}

	public static long getIntervalForOneDayInMillis()
	{
		long oneDayInMillis = 86400000L;
		return oneDayInMillis;
	}

	public static String getDateString(Date date, String pattern)
	{
		String str = null;
		SimpleDateFormat format = new SimpleDateFormat();
		format.applyPattern(pattern);
		str = format.format(date);
		return str;
	}

	public static String getDateString(Date date)
	{
		if (date == null)
		{
			return null;
		}
		else
		{
			String str = null;
			SimpleDateFormat format = new SimpleDateFormat();
			format.applyPattern("yyyy-MM-dd");
			str = format.format(date);
			return str;
		}
	}

	public static Date getCurDate() throws ParseException
	{
		Date re = null;
		SimpleDateFormat format = new SimpleDateFormat();
		format.applyPattern("yyyy-MM-dd");
		re = format.parse(getDateString(new Date()));
		return re;
	}

	public static Date nowDate()
	{
		return new Date();
	}

	public static Timestamp getDayStart(Timestamp stamp)
	{
		return getDayStart(stamp, 0);
	}

	public static Timestamp getDayStart(Timestamp stamp, int daysLater)
	{
		Calendar tempCal = Calendar.getInstance();
		tempCal.setTime(new Date(stamp.getTime()));
		tempCal.set(tempCal.get(1), tempCal.get(2), tempCal.get(5), 0, 0, 0);
		tempCal.add(5, daysLater);
		Timestamp retStamp = new Timestamp(tempCal.getTime().getTime());
		retStamp.setNanos(0);
		return retStamp;
	}

	public static Timestamp getNextDayStart(Timestamp stamp)
	{
		return getDayStart(stamp, 1);
	}

	public static Timestamp getDayEnd(Timestamp stamp)
	{
		return getDayEnd(stamp, 0);
	}

	public static Timestamp getDayEnd(Timestamp stamp, int daysLater)
	{
		Calendar tempCal = Calendar.getInstance();
		tempCal.setTime(new Date(stamp.getTime()));
		tempCal.set(tempCal.get(1), tempCal.get(2), tempCal.get(5), 23, 59, 59);
		tempCal.add(5, daysLater);
		Timestamp retStamp = new Timestamp(tempCal.getTime().getTime());
		retStamp.setNanos(999999999);
		return retStamp;
	}

	public static Timestamp getYearStart(Timestamp stamp)
	{
		return getYearStart(stamp, 0, 0);
	}

	public static Timestamp getYearStart(Timestamp stamp, int daysLater)
	{
		return getYearStart(stamp, daysLater, 0);
	}

	public static Timestamp getYearStart(Timestamp stamp, int daysLater, int yearsLater)
	{
		Calendar tempCal = Calendar.getInstance();
		tempCal.setTime(new Date(stamp.getTime()));
		tempCal.set(tempCal.get(1), 0, 1, 0, 0, 0);
		tempCal.add(5, daysLater);
		tempCal.add(1, yearsLater);
		Timestamp retStamp = new Timestamp(tempCal.getTime().getTime());
		retStamp.setNanos(0);
		return retStamp;
	}

	public static Timestamp getMonthStart(Timestamp stamp)
	{
		return getMonthStart(stamp, 0, 0);
	}

	public static Timestamp getMonthStart(Timestamp stamp, int daysLater)
	{
		return getMonthStart(stamp, daysLater, 0);
	}

	public static Timestamp getMonthStart(Timestamp stamp, int daysLater, int monthsLater)
	{
		Calendar tempCal = Calendar.getInstance();
		tempCal.setTime(new Date(stamp.getTime()));
		tempCal.set(tempCal.get(1), tempCal.get(2), 1, 0, 0, 0);
		tempCal.add(5, daysLater);
		tempCal.add(2, monthsLater);
		Timestamp retStamp = new Timestamp(tempCal.getTime().getTime());
		retStamp.setNanos(0);
		return retStamp;
	}

	public static Timestamp getWeekStart(Timestamp stamp)
	{
		return getWeekStart(stamp, 0, 0);
	}

	public static Timestamp getWeekStart(Timestamp stamp, int daysLater)
	{
		return getWeekStart(stamp, daysLater, 0);
	}

	public static Timestamp getWeekStart(Timestamp stamp, int daysLater, int weeksLater)
	{
		Calendar tempCal = Calendar.getInstance();
		tempCal.setTime(new Date(stamp.getTime()));
		tempCal.set(tempCal.get(1), tempCal.get(2), tempCal.get(5), 0, 0, 0);
		tempCal.add(5, daysLater);
		tempCal.set(7, tempCal.getFirstDayOfWeek());
		tempCal.add(4, weeksLater);
		Timestamp retStamp = new Timestamp(tempCal.getTime().getTime());
		retStamp.setNanos(0);
		return retStamp;
	}

	public static java.sql.Date toSqlDate(String date)
	{
		Date newDate = toDate(date, "00:00:00");
		if (newDate != null)
			return new java.sql.Date(newDate.getTime());
		else return null;
	}

	public static java.sql.Date toSqlDate(String monthStr, String dayStr, String yearStr)
	{
		Date newDate = toDate(monthStr, dayStr, yearStr, "0", "0", "0");
		if (newDate != null)
			return new java.sql.Date(newDate.getTime());
		else return null;
	}

	public static java.sql.Date toSqlDate(int month, int day, int year)
	{
		Date newDate = toDate(month, day, year, 0, 0, 0);
		if (newDate != null)
			return new java.sql.Date(newDate.getTime());
		else return null;
	}

	public static Time toSqlTime(String time)
	{
		Date newDate = toDate("1/1/1970", time);
		if (newDate != null)
			return new Time(newDate.getTime());
		else return null;
	}

	public static Time toSqlTime(String hourStr, String minuteStr, String secondStr)
	{
		Date newDate = toDate("0", "0", "0", hourStr, minuteStr, secondStr);
		if (newDate != null)
			return new Time(newDate.getTime());
		else return null;
	}

	public static Time toSqlTime(int hour, int minute, int second)
	{
		Date newDate = toDate(0, 0, 0, hour, minute, second);
		if (newDate != null)
			return new Time(newDate.getTime());
		else return null;
	}

	public static Timestamp toTimestamp(String dateTime)
	{
		Date newDate = toDate(dateTime);
		if (newDate != null)
			return new Timestamp(newDate.getTime());
		else return null;
	}

	public static Timestamp toTimestamp(String date, String time)
	{
		Date newDate = toDate(date, time);
		if (newDate != null)
			return new Timestamp(newDate.getTime());
		else return null;
	}

	public static Timestamp toTimestamp(String monthStr, String dayStr, String yearStr, String hourStr, String minuteStr, String secondStr)
	{
		Date newDate = toDate(monthStr, dayStr, yearStr, hourStr, minuteStr, secondStr);
		if (newDate != null)
			return new Timestamp(newDate.getTime());
		else return null;
	}

	public static Timestamp toTimestamp(int month, int day, int year, int hour, int minute, int second)
	{
		Date newDate = toDate(month, day, year, hour, minute, second);
		if (newDate != null)
			return new Timestamp(newDate.getTime());
		else return null;
	}

	public static Date toDate(String dateTime)
	{
		if (dateTime == null)
		{
			return null;
		}
		else
		{
			String date = dateTime.substring(0, dateTime.indexOf(" "));
			String time = dateTime.substring(dateTime.indexOf(" ") + 1);
			return toDate(date, time);
		}
	}

	public static Date toDate(String date, String time)
	{
		if (date == null || time == null) return null;
		int dateSlash1 = date.indexOf("/");
		int dateSlash2 = date.lastIndexOf("/");
		if (dateSlash1 <= 0 || dateSlash1 == dateSlash2) return null;
		int timeColon1 = time.indexOf(":");
		int timeColon2 = time.lastIndexOf(":");
		if (timeColon1 <= 0) return null;
		String month = date.substring(0, dateSlash1);
		String day = date.substring(dateSlash1 + 1, dateSlash2);
		String year = date.substring(dateSlash2 + 1);
		String hour = time.substring(0, timeColon1);
		String minute;
		String second;
		if (timeColon1 == timeColon2)
		{
			minute = time.substring(timeColon1 + 1);
			second = "0";
		}
		else
		{
			minute = time.substring(timeColon1 + 1, timeColon2);
			second = time.substring(timeColon2 + 1);
		}
		return toDate(month, day, year, hour, minute, second);
	}

	public static Date toDate(String monthStr, String dayStr, String yearStr, String hourStr, String minuteStr, String secondStr)
	{
		int month;
		int day;
		int year;
		int hour;
		int minute;
		int second;
		try
		{
			month = Integer.parseInt(monthStr);
			day = Integer.parseInt(dayStr);
			year = Integer.parseInt(yearStr);
			hour = Integer.parseInt(hourStr);
			minute = Integer.parseInt(minuteStr);
			second = Integer.parseInt(secondStr);
		}
		catch (Exception e)
		{
			return null;
		}
		return toDate(month, day, year, hour, minute, second);
	}

	public static Date toDate(int month, int day, int year, int hour, int minute, int second)
	{
		Calendar calendar = Calendar.getInstance();
		try
		{
			calendar.set(year, month - 1, day, hour, minute, second);
		}
		catch (Exception e)
		{
			return null;
		}
		return new Date(calendar.getTime().getTime());
	}

	public static Timestamp monthBegin()
	{
		Calendar mth = Calendar.getInstance();
		mth.set(5, 1);
		mth.set(11, 0);
		mth.set(12, 0);
		mth.set(13, 0);
		mth.set(14, 0);
		mth.set(9, 0);
		return new Timestamp(mth.getTime().getTime());
	}

	public static int weekNumber(Timestamp input)
	{
		Timestamp yearStart = getYearStart(input);
		Timestamp weekStart = getWeekStart(yearStart);
		Timestamp weekStart1 = weekStart;
		int days = 0;
		for (; getDayStart(weekStart).compareTo(yearStart) < 0; weekStart = getDayStart(weekStart, 1))
			days++;

		Timestamp week1Start = weekStart;
		if (days > 4) week1Start = getWeekStart(week1Start, 7);
		int weeks;
		for (weeks = 0; getDayStart(week1Start, weeks * 7).compareTo(input) <= 0; weeks++)
			;
		return weeks;
	}

	public static int weekSumNumber(Timestamp input)
	{
		Timestamp yearStart = getYearStart(input);
		Timestamp yearEnd = getYearStart(new Timestamp(input.getTime()), -1, 1);
		Timestamp weekStart = getWeekStart(yearStart);
		Timestamp weekStart1 = weekStart;
		int days = 0;
		for (; getDayStart(weekStart).compareTo(yearStart) < 0; weekStart = getDayStart(weekStart, 1))
			days++;

		Timestamp week1Start = weekStart;
		if (days > 4) week1Start = getWeekStart(week1Start, 7);
		days = 0;
		Timestamp weekStart2 = getWeekStart(yearEnd);
		Timestamp weekStart3 = weekStart2;
		for (; getDayStart(weekStart2).compareTo(yearEnd) < 0; weekStart2 = getDayStart(weekStart2, 1))
			days++;

		if (days <= 3) yearEnd = getDayStart(yearEnd, -7);
		int weeks;
		for (weeks = 0; getDayStart(week1Start, weeks * 7).compareTo(yearEnd) <= 0; weeks++)
			;
		return weeks;
	}

	public static int quarterNumber(Timestamp input)
	{
		int q = input.getMonth() / 3 + 1;
		return q;
	}

	public static Timestamp getQuarterStart(Timestamp input)
	{
		Calendar rightNow = Calendar.getInstance();
		rightNow.setTime(input);
		int month = rightNow.get(2) + 1;
		int mod = month / 3;
		if (month <= 3)
			month = 1;
		else if (month <= 6)
			month = 4;
		else if (month <= 9)
			month = 7;
		else month = 10;
		rightNow.set(rightNow.get(1), month - 1, rightNow.get(5));
		Timestamp quarterStart = getMonthStart(new Timestamp(rightNow.getTime().getTime()));
		return new Timestamp(quarterStart.getTime());
	}

	public static Timestamp getQuarterStart(Timestamp input, int quarterLater)
	{
		return getQuarterStart(getTimestamp(addMonth(input, 3 * quarterLater).getTime()));
	}

	public static int weekAge(Date feedDate, Date baseDate)
	{
		int weekage = 0;
		weekage = (new Double((dateDiffInDays(feedDate, baseDate) + 1) / 7)).intValue() + 1;
		return weekage;
	}


}
